home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d882.lha / GALer / GALer_english / Source / GALerSrcE.lha / GALasm.c < prev    next >
C/C++ Source or Header  |  1993-05-22  |  31KB  |  1,198 lines

  1. /****************************************************************/
  2. /*                                */
  3. /* GALAsm.c - enthält GAL-Assembler                */
  4. /*                                */
  5. /* compilieren: cc GALAsm.c                    */
  6. /*                                */
  7. /****************************************************************/
  8.  
  9.  
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <intuition/intuition.h>
  14. #include <ctype.h>
  15. #include <stdio.h>
  16. #include <functions.h>
  17.  
  18. #include "GALer.h"
  19.  
  20.  
  21.  
  22. extern    int    linenum, MaxFuseAdr, SigAdr, GALType;
  23. extern    UBYTE    *actptr, *buffend;
  24. extern  char    path;
  25.  
  26. extern    struct    JedecStruct    Jedec;
  27. extern    struct    Configuration    Config;
  28. extern    struct    RastPort    *rp;
  29. extern    struct    MenuItem    MenuItem13, MenuItem13b;  /*GAL16V8, GAL20V8*/
  30.  
  31.  
  32. struct    Pin        actPin;
  33. struct    GAL_OLMC    OLMC[8];
  34.  
  35.  
  36.             /*Diese Arrays geben an in welche Spalte der ent- */
  37.             /*sprechende Pin eingekoppelt (bzw. rückgekoppelt)*/
  38.             /*wird. Für die invertierende Einkopplung ist 1 zu*/
  39.             /*addieren, um die entsprechende Spalte zu erhalten*/
  40.             /* -1: keine Einkopplung auf Fuse-Matrix vorhanden */
  41.             /*GAL16V8:*/
  42. int    PinToFuse16Mode1[20]    = {  2, 0, 4, 8,12,16,20,24,28,-1,
  43.                     30,26,22,18,-1,-1,14,10, 6,-1 };
  44. int    PinToFuse16Mode2[20]    = {  2, 0, 4, 8,12,16,20,24,28,-1,
  45.                     30,-1,26,22,18,14,10, 6,-1,-1 };
  46. int    PinToFuse16Mode3[20]    = { -1, 0, 4, 8,12,16,20,24,28,-1,
  47.                     -1,30,26,22,18,14,10, 6, 2,-1 };
  48.  
  49.             /*GAL20V8:*/
  50. int    PinToFuse20Mode1[24]    = {  2, 0, 4, 8,12,16,20,24,28,32,36,-1,
  51.                     38,34,30,26,22,-1,-1,18,14,10, 6,-1 };
  52. int    PinToFuse20Mode2[24]    = {  2, 0, 4, 8,12,16,20,24,28,32,36,-1,
  53.                     38,34,-1,30,26,22,18,14,10,-1, 6,-1 };
  54. int    PinToFuse20Mode3[24]    = { -1, 0, 4, 8,12,16,20,24,28,32,36,-1,
  55.                     -1,38,34,30,26,22,18,14,10, 6, 2,-1 };
  56.  
  57.             /*dieses Array gibt an in welcher Zeile der*/
  58.             /*erste Eingang der OLMC-Zelle liegt*/
  59. int    ToOLMC[8]        = { 56,48,40,32,24,16, 8, 0 };
  60.  
  61.  
  62.  
  63. UBYTE    PinNames[24][10], PinNamesOpt[24][10];
  64. UBYTE    PinDecNeg[24];
  65. UBYTE    ModeErrorStr[] = "Mode  x:  Pin xx";
  66. UBYTE    *pinnames;
  67.  
  68.  
  69. LONG    fsize;
  70. UBYTE    *fbuff;
  71.  
  72. int    num_of_pins, num_of_col, modus, gal_type;
  73. int    asmreadyflag;
  74.  
  75.  
  76. /* AssembleInputFile:
  77.    Eingabe-Datei assemblieren
  78.    Aufruf: AssembleInputFile(OpMode);    (OpMode = OperationMode)
  79.    Parameter: OpMode = ASSEMBLER : assembliere das Source-File und erstelle
  80.                    die Jedec-Struktur
  81.              = OPTIMIZER : assembliere das Source-File bis zu den
  82.                    Booleschen Gleichung und brich dann ab
  83.    Ergebnis: 0: alles o.k.   sonst: Fehler oder Abbruch
  84. */
  85. int AssembleInputFile(OpMode)
  86. int    OpMode;
  87. {
  88. UBYTE    chr;
  89. UBYTE    *bool_start;
  90. char    prevOp;
  91. char    *filereqtxt;
  92. int    i, j, k, l, n, m;
  93. int    oldMaxFuseAdr, max_chr;
  94. int    pass, pin_num, bool_linenum;
  95. int    actOLMC, row_offset, a_type, newline, oldline;
  96.  
  97.  
  98. m = YES;
  99. if (OpMode == ASSEMBLER)
  100.   m = AsmRequester();
  101.  
  102. if (m) {
  103.  if (OpMode == ASSEMBLER)
  104.    filereqtxt = (char *)"Load source file";
  105.  else
  106.    filereqtxt = (char *)"load too optimizing source file";
  107.  
  108.  if (MyFileReq(filereqtxt,(char *)".pld",YES)) {
  109.    fsize=FileSize(&path);
  110.    switch (fsize) {
  111.      case -1L: {
  112.        ErrorReq(1);
  113.        return(-1);
  114.        break;
  115.       }
  116.      case -2L: {
  117.        ErrorReq(2);
  118.        return(-2);
  119.        break;
  120.       }
  121.      case 0L: {
  122.        ErrorReq(4);
  123.        return(-4);
  124.        break;
  125.       }
  126.     }
  127.    if ((fbuff=(UBYTE *)AllocMem(fsize,MEMF_PUBLIC))) {
  128.      if ((ReadFile(&path,fsize,fbuff))) {
  129.        PrintText((UBYTE *)"file loaded",1);
  130.  
  131.  
  132.        actptr  = fbuff;
  133.        buffend = fbuff+fsize;
  134.        linenum = 1;
  135.  
  136.        for (n=0; n<sizeof(Jedec); n++) {    /*Jedec-Sruktur zurücksetzen*/
  137.      if (n < LOGIC20_SIZE)
  138.        Jedec.GALLogic[n] = 1;        /*Fuse-Matrix auf 1*/
  139.      else
  140.        Jedec.GALLogic[n] = 0;        /*ACW, PT usw. auf 0*/
  141.     }
  142.  
  143.        for (n=0; n<8; n++) {            /*OLMC-Sruktur auf 0 setzen*/
  144.      OLMC[n].Active   = 0;
  145.      OLMC[n].PinType  = 0;
  146.      OLMC[n].TriCon   = 0;
  147.      OLMC[n].FeedBack = 0;
  148.     }
  149.  
  150.                     /*GAL-Typ feststellen*/
  151.        a_type = 0;
  152.        if ((!strncmp(actptr,(UBYTE *)"GAL16V8A",8)) || (!strncmp(actptr,(UBYTE *)"GAL20V8A",8)) ||
  153.            (!strncmp(actptr,(UBYTE *)"GAL16V8B",8)) || (!strncmp(actptr,(UBYTE *)"GAL20V8B",8))) {
  154.      a_type = 1;
  155.      if ( (*(actptr+8L) != ' ') && (*(actptr+8L) != 0x0A) && (*(actptr+8L) != 0x09) ) {
  156.        AsmError(1);
  157.        return(-1);
  158.       }
  159.     }
  160.  
  161.        if (!strncmp(actptr,(UBYTE *)"GAL16V8",7)) {
  162.      num_of_pins = 20;            /*Anzahl der Pins   */
  163.      num_of_col  = MAX_FUSE_ADR16 + 1;    /*Anzahl der Spalten*/
  164.      gal_type    = GAL16V8;
  165.         }
  166.        else
  167.          if (!strncmp(actptr,(UBYTE *)"GAL20V8",7)) {
  168.        num_of_pins = 24;            /*Anzahl der Pins   */
  169.        num_of_col  = MAX_FUSE_ADR20 + 1;    /*Anzahl der Spalten*/
  170.        gal_type    = GAL20V8;
  171.       }
  172.      else {
  173.        AsmError(1);
  174.        return(-1);
  175.       }
  176.  
  177.        if ((!a_type) && ((*(actptr+7L) != ' ') && (*(actptr+7L) != 0x0A) && (*(actptr+7L) != 0x09))) {
  178.      AsmError(1);
  179.      return(-1);
  180.     }
  181.  
  182.  
  183.                     /*Signatur (8 Bytes der 2.Zeile) in Puffer schreiben*/
  184.        if (GetNextLine()) {            /*Datei-Ende erreicht?*/
  185.      AsmError(2);                /*ja, dann Fehler*/
  186.      return(-1);
  187.     }
  188.        n = m = 0;                /*Signatur in Jedec-Stuktur schreiben*/
  189.        while((*actptr != 0x0A) && (*actptr != 0x09) && (n < 8)) { /*CR,TAB*/
  190.      chr = *actptr;
  191.      for (m=0; m<8; m++) {
  192.        Jedec.GALSig[n*8+m] = (chr>>(7-m)) & 0x1; 
  193.       }
  194.      actptr++;
  195.      n++;
  196.      if (actptr>buffend) {            /*Fileende erreicht ?*/
  197.        AsmError(2);                /*ja, dann Fehler*/
  198.        return(-1);
  199.       }
  200.     } 
  201.  
  202.                     /*Pin-Namen eintragen*/
  203.        for (n=0; n<24; PinDecNeg[n++]=0); /*Merker für Neg. bei Pindeklara-*/
  204.                       /*tion*/
  205.  
  206.        pinnames = &PinNames[0][0];    /*für Assembler in "PinNames"*/
  207.        if (OpMode == OPTIMIZER)
  208.      pinnames = &PinNamesOpt[0][0];    /*für Optimizer in "PinNamesOpt"*/
  209.  
  210.        asmreadyflag = 0;            /*noch nicht assembliert*/
  211.        GetNextLine();
  212.        for (n=0; n<num_of_pins; n++) {
  213.       if (GetNextChar()) {            /*Dateiende?*/
  214.         AsmError(2);            /*ja, dann Fehler*/
  215.         return(-1);
  216.        }
  217.       m = 0;
  218.       chr = *actptr;
  219.       if (chr == '/') {
  220.         max_chr      = 10;
  221.         PinDecNeg[n] = 1;            /*Neg. bei Pindeklaration*/
  222.        }
  223.       else
  224.         max_chr = 9;
  225.       if (!(isalpha(chr) || isdigit(chr) || chr=='/')) {
  226.         AsmError(5);
  227.         return(-1);
  228.        }
  229.       k = 0;
  230.       while (isalpha(chr) || isdigit(chr) || chr=='/') {
  231.          if ((chr == '/') && (k != 0)) {    /* '/' nicht am Anfang des Pinnamens?*/
  232.            AsmError(10);
  233.            return(-1);
  234.           }
  235.          k = 1;
  236.          actptr++;
  237.          if ((chr=='/') && (!(isalpha(*actptr) || isdigit(*actptr)))) {
  238.            AsmError(3);
  239.            return(-1);
  240.           }
  241.          *(pinnames+n*10+m) = chr;
  242.          m++;
  243.          chr = *actptr;
  244.          if (m == max_chr) {        /*zuviele Buchstaben?*/
  245.            AsmError(4);
  246.            return(-1);
  247.           }
  248.         }
  249.       *(pinnames+n*10+m) = 0;        /*Stringende kennzeichnen*/
  250.  
  251.       for (l=0; l<n; l++) {            /*Pinname doppelt?*/
  252.         if (strcmp(pinnames+l*10,(UBYTE *)"NC")) {
  253.           i = j = 0;
  254.           if (*(pinnames+l*10) == '/') i = 1;
  255.           if (*(pinnames+n*10) == '/') j = 1;
  256.           if (!strcmp(pinnames+l*10+i,pinnames+n*10+j)) {
  257.         AsmError(9);
  258.         return(-1);
  259.            }
  260.          }
  261.        }
  262.                         /*GND an entsprechenden Pin?*/
  263.       if (!strcmp(pinnames+n*10,(UBYTE *)"GND")) {
  264.         if (n+1 != num_of_pins/2) {
  265.           AsmError(6);
  266.           return(-1);
  267.          }
  268.        }
  269.       if (n+1 == num_of_pins/2) {
  270.         if (strcmp(pinnames+n*10,(UBYTE *)"GND")) {
  271.           AsmError(8);
  272.           return(-1);
  273.          }
  274.        }
  275.                         /*VCC an entsprechenden Pin?*/
  276.       if (!strcmp(pinnames+n*10,(UBYTE *)"VCC")) {
  277.         if (n+1 != num_of_pins) {
  278.           AsmError(6);
  279.           return(-1);
  280.          }
  281.        }
  282.       if (n+1 == num_of_pins) {
  283.         if (strcmp(pinnames+n*10,(UBYTE *)"VCC")) {
  284.           AsmError(7);
  285.           return(-1);
  286.          }
  287.        }
  288.     }
  289.  
  290.  
  291.       if (OpMode == OPTIMIZER)        /*falls vom Optimizer aufgerufen,*/
  292.     return(0);            /*dann fertig*/
  293.  
  294.  
  295.  
  296. /* Boolean-Equations auswerten:
  297.    Dabei werden die Boolean-Equations zweimal untersucht. Beim ersten
  298.    Durchlauf werden die OLMC-Pins ausgewertet und die OLMC-Struktur ge-
  299.    füllt. Mit Hilfe dieser Struktur läßt sich auf dem notwendigen Modus
  300.    (1, 2 oder 3) schließen. Beim zweiten Durchlauf wird dann die
  301.    Fuse-Matrix erstellt.
  302.  */
  303.  
  304.        if (GetNextChar()) {            /*Dateiende?*/
  305.      AsmError(2);                /*ja, dann Fehler*/
  306.      return(-1);
  307.     }
  308.  
  309.                         /*Gleichungen vorhanden?*/
  310.        if (!strncmp(actptr,(UBYTE *)"DESCRIPTION",11)) {
  311.      AsmError(33);                /*nein, dann Fehlermeldung*/
  312.      return(-1);
  313.     }
  314.  
  315.  
  316.        bool_start   = actptr;            /*Zeiger auf Anfang der Equations*/
  317.        bool_linenum = linenum;            /*Zeilennummer merken*/
  318.  
  319.        for (pass=0; pass<2; pass++) {        /*2 Durchläufe*/
  320.  
  321.      if (pass) {            /*2. Durchlauf?->ACW erstellen*/
  322.        modus = 0;            /*und Modus bestimmen*/
  323.        for (n=0; n<8; n++) {        /*alle OLMCs untersuchen*/
  324.          if (OLMC[n].PinType == REGOUT) {    /*OLMC als Reg. vorhanden?*/
  325.            modus = MODE3;            /*ja, dann MUß Mode3 vorliegen*/
  326.            Jedec.GALSYN = 0;        /*SYN- und AC0-Bit setzen*/
  327.            Jedec.GALAC0 = 1;
  328.            break;
  329.           }
  330.         }
  331.  
  332.        if (!modus) {
  333.          for (n=0; n<8; n++) {
  334.            if (OLMC[n].PinType == TRIOUT) {    /*OLMC als Tri. vorhanden?*/
  335.              modus = MODE2;            /*ja, dann Mode2*/
  336.              Jedec.GALSYN = 1;        /*SYN- und AC0-Bit setzen*/
  337.              Jedec.GALAC0 = 1;
  338.          break;
  339.             }
  340.           }
  341.         }
  342.  
  343.  
  344.        if (!modus) {            /*wenn Verstöße gegen Mode1,*/
  345.          for (n=0; n<8; n++) {        /*dann automatisch in Mode2*/
  346.            if (OLMC[n].PinType == INPUT) {    /*schalten*/
  347.              if (gal_type == GAL16V8) {
  348.            pin_num = n + 12;
  349.                if ((pin_num == 15) || (pin_num == 16)) {
  350.              modus = MODE2;        /*Mode2*/
  351.              Jedec.GALSYN = 1;        /*SYN- und AC0-Bit setzen*/
  352.              Jedec.GALAC0 = 1;
  353.              break;
  354.                 }
  355.               }
  356.              if (gal_type == GAL20V8) {
  357.            pin_num = n + 15;
  358.                if ((pin_num == 18) || (pin_num == 19)) {
  359.              modus = MODE2;        /*Mode2*/
  360.              Jedec.GALSYN = 1;        /*SYN- und AC0-Bit setzen*/
  361.              Jedec.GALAC0 = 1;
  362.              break;
  363.                 }
  364.               }
  365.             }        /*wenn Ausgang mit Rückkopplung, dann Mode2*/
  366.            if ((OLMC[n].PinType == COM_TRI_OUT) && (OLMC[n].FeedBack)) {
  367.          modus = MODE2;            /*Mode2*/
  368.          Jedec.GALSYN = 1;        /*SYN- und AC0-Bit setzen*/
  369.          Jedec.GALAC0 = 1;
  370.          break;
  371.         }
  372.           }
  373.         }
  374.  
  375.  
  376.        if (!modus) {
  377.          modus = MODE1;            /*noch kein Mode? dann Mode1*/
  378.          Jedec.GALSYN = 1;            /*SYN- und AC0-Bit setzen*/
  379.          Jedec.GALAC0 = 0;
  380.         }
  381.  
  382.  
  383.  
  384.                     /*falls Modus 1 voliegt, alle*/
  385.                     /*Ausgänge deren Typ nicht an-*/
  386.                     /*gegeben wurde in komb. Ausgänge*/
  387.                     /*umwandeln*/
  388.                     /*falls Modus 2 oder 3 vorliegt,*/
  389.                     /*alle Ausgänge deren Typ nicht an-*/
  390.                     /*gegeben wurde in Tristate mit per-*/
  391.        for (n=0; n<8; n++) {    /*manenter Freischaltung umwandeln*/
  392.          if (OLMC[n].PinType == COM_TRI_OUT) {
  393.            if (modus == MODE1) {
  394.          OLMC[n].PinType = COMOUT;
  395.         }
  396.            else {
  397.              OLMC[n].PinType = TRIOUT;
  398.              OLMC[n].TriCon  = TRI_VCC;
  399.         }
  400.           }
  401.         }
  402.     
  403.                     /*ACW erstellen: SYN und AC0 sind*/
  404.                     /*bereits festgelegt*/
  405.        for (n=0; n<PT_SIZE; n++)        /*Produkftermfreigabe auf 1*/
  406.          Jedec.GALPT[n] = 1;
  407.  
  408.                     /*AC1-Bits bestimmen*/
  409.        for (n=0; n<AC1_SIZE; n++) {
  410.          if ((OLMC[n].PinType == INPUT) || (OLMC[n].PinType == TRIOUT))
  411.            Jedec.GALAC1[AC1_SIZE-1-n] = 1;
  412.         }
  413.  
  414.        for (n=0; n<XOR_SIZE; n++) {        /*XOR-Bits bestimmen*/
  415.          if (((OLMC[n].PinType == COMOUT) ||
  416.           (OLMC[n].PinType == TRIOUT) ||
  417.           (OLMC[n].PinType == REGOUT)) &&
  418.           (OLMC[n].Active  == ACTIVE_HIGH))
  419.            Jedec.GALXOR[XOR_SIZE-1-n] = 1;
  420.         }
  421.  
  422.       }
  423.  
  424.  
  425.  
  426.      actptr  = bool_start;
  427.      linenum = bool_linenum;
  428.      newline = linenum;
  429.          goto label1;
  430.  
  431. loop1:     if (GetNextChar()) {                /*Dateiende?*/
  432.        AsmError(2);                    /*ja, dann Fehler*/
  433.        return(-1);
  434.       }
  435.      chr = 0x00;
  436.      if (*actptr == '.') {
  437.        actptr++;
  438.        chr = *actptr;
  439.        if (!((chr == 'T') || (chr == 'E') || (chr == 'R'))) {
  440.          AsmError(13);
  441.          return(-1);
  442.         }         
  443.        actptr++;
  444.        if (GetNextChar()) {                /*Dateiende?*/
  445.          AsmError(2);                /*ja, dann Fehler*/
  446.          return(-1);
  447.         }
  448.       }
  449.  
  450.      actOLMC = (int)actPin.p_Pin;        /*OLMC-Offset merken*/
  451.      if (gal_type == GAL16V8)
  452.        actOLMC -= 12;
  453.      else
  454.        actOLMC -= 15;
  455.      row_offset  = 0;            /*Offset für OR am OLMC*/
  456.      prevOp         = 0;            /*vorherige Verknüpfung*/
  457.                         /*chr enthält T,R,E oder 0x00*/
  458.      if (!pass) {                /*Pass 1?*/
  459.        if ( ((gal_type == GAL16V8)        /*OLMC-Pin?*/
  460.          && (actPin.p_Pin >= 12) && (actPin.p_Pin <= 19)) ||
  461.         ((gal_type == GAL20V8)
  462.          && (actPin.p_Pin >= 15) && (actPin.p_Pin <= 22)) ) {
  463.          if (gal_type == GAL16V8)
  464.            n=actPin.p_Pin-12;
  465.          if (gal_type == GAL20V8)
  466.            n=actPin.p_Pin-15;
  467.          if (chr != 'E') {            /*keine Tristate-Freigabe?*/
  468.                         /*mehrfache Zuweisung?*/
  469.            if ((!OLMC[n].PinType) || (OLMC[n].PinType == INPUT)) {
  470.          if (actPin.p_Neg)
  471.            OLMC[n].Active = ACTIVE_LOW;
  472.          else
  473.            OLMC[n].Active = ACTIVE_HIGH;
  474.  
  475.          switch (chr) {
  476.            case 'T': { OLMC[n].PinType = TRIOUT;
  477.                    break;
  478.                  }
  479.            case 'R': { OLMC[n].PinType = REGOUT;
  480.                    break;
  481.                  }
  482.            case 0x00:{ OLMC[n].PinType = COM_TRI_OUT;
  483.                    break;
  484.                  }
  485.           }
  486.         }
  487.            else {
  488.          AsmError(16);
  489.          return(-1);
  490.         }
  491.           }
  492.          else {
  493.            if (OLMC[n].PinType == TRIOUT) {
  494.          if (actPin.p_Neg)        /*bei Tri.-Kontrolle '/'*/
  495.            actPin.p_Neg = 0;        /*nicht beachten*/
  496.          if (OLMC[n].TriCon) {        /*Tri.-Kontrolle doppelt?*/
  497.            AsmError(22);
  498.            return(-1);
  499.           }
  500.          OLMC[n].TriCon = TRICON;    /*Tri.-Kontrolle angegeben*/
  501.         }
  502.            if ((!OLMC[n].PinType) || (OLMC[n].PinType == INPUT)) {
  503.          AsmError(17);            /*zuerst Tri.Kon.?*/
  504.          return(-1);            /*dann Fehler*/
  505.         }
  506.            if (OLMC[n].PinType == REGOUT) { /*Register? dann Fehler*/
  507.          AsmError(23);
  508.          return(-1);
  509.         }
  510.            if (OLMC[n].PinType == COM_TRI_OUT) { /*kein klares .T?*/
  511.          AsmError(24);
  512.          return(-1);
  513.         }
  514.           }
  515.         }
  516.        else {
  517.          AsmError(15);
  518.          return(-1);
  519.         }
  520.       }
  521.  
  522.  
  523.  
  524.      if (*actptr != '=') {                /* '=' ?*/
  525.        AsmError(14);                /*nein, dann Fehler*/
  526.        return(-1);
  527.       }         
  528. loop2:
  529.      actptr++;
  530.      if (GetNextChar()) {                /*Dateiende?*/
  531.        AsmError(2);                    /*ja, dann Fehler*/
  532.        return(-1);
  533.           }
  534.      IsPinName(pinnames,num_of_pins);
  535.      if (!actPin.p_Pin) {                /*Pinname?*/
  536.        AsmError(11);                /*nein, dann Fehler*/
  537.        return(-1);
  538.       }
  539.      if (actPin.p_Pin == NC_PIN) {            /*NC als Pinname?*/
  540.        AsmError(12);                /*ja, dann Fehler*/
  541.        return(-1);
  542.       }
  543.      if (*(pinnames+(long)((actPin.p_Pin-1)*10)) == '/') {
  544.        actPin.p_Neg = !actPin.p_Neg;    /*Negation bei Pindek.*/
  545.       }                    /*berücksichtigen*/
  546.      oldline = linenum;
  547.      if (GetNextChar()) {                /*Dateiende?*/
  548.        AsmError(2);                    /*ja, dann Fehler*/
  549.        return(-1);
  550.       }
  551.      newline = linenum;
  552.      linenum = oldline;
  553.  
  554.      if (!pass) {                    /*Pass 1?*/
  555.        if ( ((gal_type == GAL16V8)            /*OLMC-Pin?*/
  556.          && (actPin.p_Pin >= 12) && (actPin.p_Pin <= 19)) ||
  557.         ((gal_type == GAL20V8)
  558.          && (actPin.p_Pin >= 15) && (actPin.p_Pin <= 22)) ) {
  559.          if (gal_type == GAL16V8)
  560.            n=actPin.p_Pin-12;
  561.          if (gal_type == GAL20V8)
  562.            n=actPin.p_Pin-15;
  563.          if (!OLMC[n].PinType) {            /*OLMC bereits def.?*/
  564.            OLMC[n].PinType = INPUT;            /*nein, dann Eingang*/
  565.           }
  566.          OLMC[n].FeedBack = YES;    /*wenn hinter dem "=" ein OLMC-Pin*/
  567.         }                /*vorkommt, dann FeedBack benötigt*/
  568.       }
  569.                     /*im 2.Durchlauf Fuse-Matrix*/
  570.                     /*erstellen; chr = T,R,E oder 0x00*/
  571.      if (pass) {
  572.        if (chr != 'E') {
  573.          if (!row_offset) {            /*Zeilenoffset noch 0?*/
  574.            if ( (modus != MODE1) && (OLMC[actOLMC].PinType != REGOUT)) {
  575.              row_offset = 1;
  576.             }
  577.           }
  578.         }
  579.                     /*auf Verstoß gegen Modus prüfen*/
  580.        pin_num = actPin.p_Pin;
  581.        if (modus == MODE2) {        /*Verstoß gegen Mode 2?*/
  582.          if ((gal_type==GAL16V8) && ((pin_num==12) || (pin_num==19))) {
  583.            AsmError(20);
  584.            return(-1);
  585.           }
  586.          if ((gal_type==GAL20V8) && ((pin_num==15) || (pin_num==22))) {
  587.            AsmError(21);
  588.            return(-1);
  589.           }
  590.         }
  591.        if (modus == MODE3) {        /*Verstoß gegen Mode 3?*/
  592.          if ((gal_type==GAL16V8) && ((pin_num==1) || (pin_num==11))) {
  593.            AsmError(26);
  594.            return(-1);
  595.           }
  596.          if ((gal_type==GAL20V8) && ((pin_num==1) || (pin_num==13))) {
  597.            AsmError(27);
  598.            return(-1);
  599.           }
  600.         }
  601.                     /*wenn GND dann Zeile auf 0 setzen*/
  602.        if ((pin_num == num_of_pins) || (pin_num == num_of_pins/2)) {
  603.          if (actPin.p_Neg) {        /*kein /VCC, /GND zulassen*/
  604.            AsmError(25);
  605.            return(-1);
  606.           }
  607.          if (!prevOp && (*actptr != '*' ) && (*actptr != '+')) {
  608.            if (pin_num == num_of_pins/2) {
  609.          if (chr == 'E')         /*bei "x.E=GND|VCC" 1.Zeile*/
  610.            m = ToOLMC[actOLMC] * num_of_col;    /*bei x, x.R, x.T*/
  611.          else                /*row_offset berücksichtigen*/
  612.            m = (ToOLMC[actOLMC] + row_offset) * num_of_col;
  613.          for (n=m; n<m+num_of_col; Jedec.GALLogic[n++]=0);
  614.         }
  615.           }
  616.          else {
  617.            AsmError(28);
  618.            return(-1);
  619.           }
  620.         }
  621.        else {
  622.          if (chr == 'E') {
  623.            if (prevOp == '+') {        /*max. 1 Produktterm*/
  624.              AsmError(29);            /*mehr, dann Fehler*/
  625.              return(-1);
  626.             }                     /*UND-Verknüpfung erstellen*/
  627.            SetAND(ToOLMC[actOLMC], pin_num, actPin.p_Neg);
  628.           }
  629.          else {
  630.            if (prevOp == '+') {        /*ODER-Verknüpfung?*/
  631.              row_offset++;            /*ja, dann nächste Zeile*/
  632.              if (row_offset == MAX_OR) {    /*zuviele Produktterme?*/
  633.            if ((modus != MODE1) && (OLMC[actOLMC].PinType != REGOUT)) {
  634.              AsmError(31);
  635.              return(-1);
  636.             }
  637.            else {
  638.              AsmError(30);
  639.              return(-1);
  640.             }
  641.           }
  642.             }                /*UND-Verknüpfung setzen*/
  643.            SetAND(ToOLMC[actOLMC]+row_offset, pin_num, actPin.p_Neg);
  644.           }
  645.         }
  646.                     /*kommt noch eine Verknüpfung?*/
  647.        if ((*actptr != '+') && (*actptr != '*') && (chr != 'E')) { /*nein*/
  648.          row_offset++;                /*Rest der OLMC- */
  649.          if (row_offset != MAX_OR) {        /*Zeilen auf 0    */
  650.            m = (ToOLMC[actOLMC] + row_offset) * num_of_col;
  651.            for (n=m; n<m+(MAX_OR-row_offset) * num_of_col; n++)
  652.          Jedec.GALLogic[n] = 0;
  653.           }
  654.         }
  655.       }
  656.  
  657.  
  658.      linenum = newline;
  659.  
  660.      if ((*actptr == '+') || (*actptr == '*')) {
  661.        prevOp = *actptr;
  662.        goto loop2;
  663.       }
  664.  
  665.  
  666.      if (strncmp(actptr,(UBYTE *)"DESCRIPTION",11)) {
  667. label1:       linenum = newline;
  668.        IsPinName(pinnames,num_of_pins);
  669.        if (!actPin.p_Pin) {                /*Pinname?*/
  670.          AsmError(11);                /*nein, dann Fehler*/
  671.          return(-1);
  672.         }
  673.        if (actPin.p_Pin==NC_PIN) {            /*NC als Pinname?*/
  674.          AsmError(12);                /*ja, dann Fehler*/
  675.          return(-1);
  676.         }
  677.        if (*(pinnames+(long)((actPin.p_Pin-1)*10)) == '/') {
  678.          actPin.p_Neg = !actPin.p_Neg;    /*Negation bei Pindek.*/
  679.         }                    /*berücksichtigen*/
  680.  
  681.        goto loop1;
  682.       }
  683.  
  684.     }
  685.                     /*Fuse-Matrix der nichtverwendeten*/
  686.                     /*OLMCs und der OLMCs die als Eingang*/
  687.                     /*programmiert sind auf 0 setzen*/
  688.        for (n=0; n<8; n++) {
  689.      if ((OLMC[n].PinType == NOTUSED) || (OLMC[n].PinType == INPUT)) {
  690.        l = ToOLMC[n];
  691.        l = l * num_of_col;
  692.        m = l + 8 * num_of_col;
  693.        for (k=l; k<m; k++)
  694.         Jedec.GALLogic[k] = 0;
  695.       }
  696.     }
  697.                     /*Jedec-Struktur ist fertig (jubel)*/
  698.  
  699.        asmreadyflag = 1;        /*File fertig assembliert*/
  700.  
  701.        FreeMem(fbuff, fsize);        /*Puffer für File .pld*/
  702.  
  703.  
  704.                     /* symbolisches GAL einstellen */
  705.                     /*gal_type: aus dem Source-File*/
  706.                     /*GALType : eingestelltes GAL*/
  707.        if (Config.AutoGAL == YES) {
  708.      if (gal_type == GAL16V8)
  709.        SetGALType (GAL16V8,a_type);
  710.      if (gal_type == GAL20V8)
  711.        SetGALType (GAL20V8,a_type);
  712.      PrintPinNames();
  713.     }
  714.  
  715.                     /* angewählte Files erstellen*/
  716.        if (Config.GenJedec==YES) {
  717.          if (MyFileReq((char *)"save JEDEC file",(char *)".jed",!Config.AutoSave)) {
  718.        oldMaxFuseAdr = MaxFuseAdr;
  719.        if (gal_type == GAL16V8) 
  720.          MaxFuseAdr = MAX_FUSE_ADR16;
  721.        else
  722.          MaxFuseAdr = MAX_FUSE_ADR20;
  723.        WriteJedecFile();
  724.        MaxFuseAdr = oldMaxFuseAdr;
  725.       }
  726.     }
  727.        if (Config.GenFuse==YES)
  728.      WriteFuseFile();
  729.        if (Config.GenChip==YES)
  730.      WriteChipFile();
  731.        if (Config.GenPin==YES)
  732.      WritePinFile();
  733.        PrintText((UBYTE *)"file assembled",1);
  734.        return(0);                /*kein Fehler aufgetreten*/
  735.       }
  736.      else {
  737.        ErrorReq(3);                /*Lesefehler*/
  738.        FreeMem(fbuff,fsize);
  739.        return(-2);
  740.       }
  741.     }
  742.    else {
  743.      ErrorReq(2);                /*kein Speicher*/
  744.      return(-2);
  745.     }
  746.   }
  747.  else return(-1);            /*Abbruch beim FileRequester*/
  748.  }
  749. else return(-1);            /*Abbruch beim AsmRequester*/
  750. }
  751.  
  752.  
  753.  
  754.  
  755.  
  756. /* setze eine UND-Verknüpfung (=0) in der Fuse-Matrix
  757.    row     :  Zeile in der die UND-Verknüpfung entstehen soll
  758.    pinnum  :  Pin der UND-verknüpft werden soll
  759.    negation:  0: Pin nicht negiert; 1: Pin negiert ('/')
  760. */
  761. void SetAND(row, pinnum, negation)
  762. int    row, pinnum, negation;
  763. {
  764. int column;
  765.  
  766.  if (gal_type == GAL16V8) {
  767.    if (modus == MODE1)
  768.      column = PinToFuse16Mode1[pinnum - 1];
  769.    if (modus == MODE2)
  770.      column = PinToFuse16Mode2[pinnum - 1];
  771.    if (modus == MODE3)
  772.      column = PinToFuse16Mode3[pinnum - 1];
  773.   }
  774.  else {
  775.    if (modus == MODE1)
  776.      column  =  PinToFuse20Mode1[pinnum - 1];
  777.    if (modus == MODE2)
  778.      column  =  PinToFuse20Mode2[pinnum - 1];
  779.    if (modus == MODE3)
  780.      column  =  PinToFuse20Mode3[pinnum - 1];
  781.   }
  782.  Jedec.GALLogic[row * num_of_col + column + negation] = 0;
  783. }
  784.  
  785.  
  786.  
  787.  
  788. /* Überprüfe ob bei "actptr" ein Pinname steht der in "pinnames" eingetragen
  789.    ist und der kein NC (not connected) ist. Die Anzahl der zu untersuchenden
  790.    Pins steht in "numofpins".
  791.    "actptr" wird auf erstes Zeichen hinter den Pinnamen gestellt
  792.    actPin.p_Pin: Pinnummer oder NC_PIN; 0: kein Pinname
  793.    actPin.p_Neg: Pinname mit '/' = 1;  ohne '/' = 0
  794. */
  795. void IsPinName(pinnames, numofpins)
  796. UBYTE    *pinnames;
  797. int    numofpins;
  798. {
  799. int    i, k, n;
  800. UBYTE    *oldactptr;
  801.  
  802.  actPin.p_Neg = 0;        /*Pin-Struktur zurücksetzen*/
  803.  actPin.p_Pin = 0;
  804.  
  805.  if (*actptr == '/' ) {        /*Negation?*/
  806.    actptr++;
  807.    actPin.p_Neg = 1;
  808.   }
  809.  
  810.  n = 0;                /*Länge des möglichen Pinnamens ermitteln*/
  811.  oldactptr = actptr;
  812.  while (isalpha(*actptr) || isdigit(*actptr)) {
  813.    actptr++;
  814.    n++;
  815.   }
  816.  
  817.  if (n)
  818.    if ((n == 2 ) && !strncmp(oldactptr,(UBYTE *)"NC",2))  /*NC ?*/
  819.      actPin.p_Pin = NC_PIN;                /*ja, dann NC-Pin*/
  820.    else
  821.      for (k=0; k<numofpins; k++) {     /*List der Pinnamen durchsuchen*/
  822.        i = 0;
  823.        if (*(pinnames+k*10) == '/')
  824.          i = 1;
  825.        if (n == strlen(pinnames+k*10+i))    /*Stringlängen gleich?*/       
  826.          if (!(strncmp(oldactptr,pinnames+k*10+i,n))) {     /*ja, dann Strings*/
  827.        actPin.p_Pin = k+1;                 /*vergeichen      */
  828.        break;
  829.           }
  830.       }
  831. }
  832.  
  833.  
  834.  
  835.  
  836. /*suche ab "actptr" das nächste Zeichen das kein Space, TAB, LF ist
  837.   Ergebins: 0:Zeichen gefunden, actptr=Zeiger auf dieses Zeichen
  838.         1:kein Zeichen mehr da
  839. */
  840. int GetNextChar()
  841. {
  842.  for(;;) {
  843.    switch (*actptr) {
  844.      case 0x0A: {                /*LineFeed*/
  845.        actptr++;
  846.        linenum++;
  847.        break;
  848.       }
  849.      case  ' ':                    /*Space*/
  850.      case 0x09: {                /*TAB*/
  851.        actptr++;
  852.        break;
  853.       }
  854.      default  : {
  855.        if ((*actptr>' ') && (*actptr<='~')) return(0);    /*Zeichen gefunden?*/
  856.        else actptr++;
  857.       }
  858.     }
  859.    if (actptr>buffend) return(1);            /*Fileende erreicht?*/
  860.   }
  861. }
  862.  
  863.  
  864. /*Zeiger auf zächste Zeile holen
  865.   Ergebins: 0:Zeile gefunden, actptr=Zeiger auf diese Zeile
  866.         1:File-Ende erreicht
  867. */
  868. int GetNextLine()
  869. {
  870.  for(;;) {
  871.    if (*actptr == 0x0A) {
  872.      actptr++;
  873.      linenum++;
  874.      return(0);
  875.     }
  876.    if (actptr>buffend) return(1);            /*Fileende erreicht*/
  877.    actptr++;
  878.   }
  879. }
  880.  
  881.  
  882.  
  883.  
  884. /* gibt Fehlermeldungen des GAL-Assemblers aus
  885.    und gibt Speicher für File-Puffer wieder frei
  886. */
  887. void AsmError(errornum)
  888. int    errornum;
  889. {
  890.  FreeMem(fbuff,fsize);
  891.  MyRequest(ERR_REQ,(UBYTE *)"error in source file");
  892.  PrintErrorLine(linenum);
  893.  switch (errornum) {
  894.    case  1:
  895.      PrintText((UBYTE *)"Line  1: type of GAL expected",1);
  896.      break;
  897.    case  2:
  898.      PrintText((UBYTE *)"unexpected end of file",1);
  899.      break;
  900.    case  3:
  901.      PrintText((UBYTE *)"pinname expected after '/'",1);
  902.      break;
  903.    case  4:
  904.      PrintText((UBYTE *)"max. length of pinname is 8 characters",1);
  905.      break;
  906.    case  5:
  907.      PrintText((UBYTE *)"illegal character in pin declaration",1);
  908.      break;
  909.    case  6:
  910.      PrintText((UBYTE *)"illegal VCC/GND assignment",1);
  911.      break;
  912.    case  7:
  913.      PrintText((UBYTE *)"pin declaration: expected VCC at VCC pin",1);
  914.      break;
  915.    case  8:
  916.      PrintText((UBYTE *)"pin declaration: expected GND at GND pin",1);
  917.      break;
  918.    case  9:
  919.      PrintText((UBYTE *)"pinname defined twice",1);
  920.      break;
  921.    case 10:
  922.      PrintText((UBYTE *)"illegal use of '/'",1);
  923.      break;
  924.    case 11:
  925.      PrintText((UBYTE *)"unknown pinname",1);
  926.      break;
  927.    case 12:
  928.      PrintText((UBYTE *)"NC (Not Connected) is not allowed in logic equations",1);
  929.      break;
  930.    case 13:
  931.      PrintText((UBYTE *)"'T', 'E' or 'R' expected after '.'",1);
  932.      break;
  933.    case 14:
  934.      PrintText((UBYTE *)"'=' expected",1);
  935.      break;
  936.    case 15:
  937.      PrintText((UBYTE *)"this pin can't be used as output",1);
  938.      break;
  939.    case 16:
  940.      PrintText((UBYTE *)"same pin is defined multible as output",1);
  941.      break;
  942.    case 17:
  943.      PrintText((UBYTE *)"Tristate control: tristate output is not defined",1);
  944.      break;
  945.  
  946.    case 20:
  947.      PrintText((UBYTE *)"Mode 2: pins 12, 19 can't be used as input",1);
  948.      break;
  949.    case 21:
  950.      PrintText((UBYTE *)"Mode 2: pins 15, 22 can't be used as input",1);
  951.      break;
  952.    case 22:
  953.      PrintText((UBYTE *)"Tristate control is defined twice",1);
  954.      break;
  955.    case 23:
  956.      PrintText((UBYTE *)"Tristate control for registered output",1);
  957.      break;
  958.    case 24:
  959.      PrintText((UBYTE *)"Tristate control without previous '.T'",1);
  960.      break;
  961.    case 25:
  962.      PrintText((UBYTE *)"use GND, VCC instead of /VCC, /GND",1);
  963.      break;
  964.    case 26:
  965.      PrintText((UBYTE *)"Mode 3: pins 1,11 are reservated for 'Clock' and '/OE'",1);
  966.      break;
  967.    case 27:
  968.      PrintText((UBYTE *)"Mode 3: pins 1,13 are reservated for 'Clock' and '/OE'",1);
  969.      break;
  970.    case 28:
  971.      PrintText((UBYTE *)"use of VCC and GND is not allowed in equations",1);
  972.      break;
  973.    case 29:
  974.      PrintText((UBYTE *)"Tristate control: only one product term allowed (no '+')",1);
  975.      break;
  976.    case 30:
  977.      PrintText((UBYTE *)"max. 8 product terms allowed",1);
  978.      break;
  979.    case 31:
  980.      PrintText((UBYTE *)"max. 7 product terms allowed",1);
  981.      break;
  982.    case 33:
  983.      PrintText((UBYTE *)"no equations found",1);
  984.      break;
  985.   }
  986. }
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993. /****************************************************************/
  994. /* ab hier stehen die Routinen, die für die Erstellung der      */
  995. /* Dokumentations-Files zuständig sind                */
  996. /****************************************************************/
  997.  
  998.  
  999. /* erstelle das Chip-File*/
  1000. void WriteChipFile()
  1001. {
  1002. extern    char    path;
  1003. FILE    *fp;
  1004. int    n;
  1005.  
  1006.    if (MyFileReq((char *)"save chip file",(char *)".chp",!Config.AutoSave)) {
  1007.      PrintText((UBYTE *)"saving chip file...",1);
  1008.      if (fp=fopen(&path,(UBYTE *)"w")) {
  1009.        fprintf(fp,"\n\n");
  1010.        WriteSpaces(fp,32);
  1011.        if (gal_type == GAL16V8)    fprintf(fp,"GAL16V8\n\n");
  1012.        else fprintf(fp,"GAL20V8\n\n");
  1013.        WriteSpaces(fp,26);
  1014.        fprintf(fp,"-------\\___/-------\n");
  1015.  
  1016.        for (n=0; n<num_of_pins/2; n++) {
  1017.      WriteSpaces(fp,25-strlen(pinnames+n*10));
  1018.      fprintf(fp,"%s | %2d           %2d | %s\n",pinnames+n*10,n+1,num_of_pins-n,pinnames+(num_of_pins-n-1)*10);
  1019.      if (n<num_of_pins/2-1) {
  1020.        WriteSpaces(fp,26);
  1021.        fprintf(fp,"|                 |\n");
  1022.       }
  1023.     }
  1024.  
  1025.        WriteSpaces(fp,26);
  1026.        fprintf(fp,"-------------------\n");
  1027.  
  1028.        if (fclose(fp)==EOF) {
  1029.      PrintText((UBYTE *)" Error! ",0);
  1030.          ErrorReq(8);            /*Datei läßt sich nicht schließen*/
  1031.      return;
  1032.     }
  1033.       }
  1034.      else {
  1035.        PrintText((UBYTE *)" Error! ",0);
  1036.        ErrorReq(13);
  1037.        return;
  1038.       }
  1039.      PrintText((UBYTE *)" o.k.",0);
  1040.     }
  1041. }
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047. /* erstelle das Pin-File*/
  1048. void WritePinFile()
  1049. {
  1050. extern    char    path;
  1051. FILE    *fp;
  1052. int    k, n, flag;
  1053.  
  1054.    if (MyFileReq((char *)"save pin file",(char *)".pin",!Config.AutoSave)) {
  1055.      PrintText((UBYTE *)"saving pin file...",1);
  1056.      if (fp=fopen(&path,(UBYTE *)"w")) {
  1057.        fprintf(fp,"\n\n");
  1058.        fprintf(fp," Pin # | Name     | Pin Type\n");
  1059.        fprintf(fp,"-----------------------------\n");
  1060.  
  1061.        for (n=1; n<=num_of_pins; n++) {
  1062.      fprintf(fp,"  %2d   | ",n);
  1063.      fprintf(fp,"%s",pinnames+(n-1)*10);
  1064.      WriteSpaces(fp,9-strlen(pinnames+(n-1)*10));
  1065.  
  1066.      flag = 0;
  1067.      if (n == num_of_pins/2) {
  1068.        fprintf(fp,"| GND\n");
  1069.        flag = 1;
  1070.       }
  1071.      if (n == num_of_pins) {
  1072.        fprintf(fp,"| VCC\n\n");
  1073.        flag = 1;
  1074.       }
  1075.      if ((modus == MODE3) && (n == 1)) {
  1076.        fprintf(fp,"| Clock\n");
  1077.        flag = 1;
  1078.       }
  1079.      if (modus == MODE3) {
  1080.        if ((gal_type == GAL16V8) && (n == 11)) {
  1081.          fprintf(fp,"| /OE\n");
  1082.          flag = 1;
  1083.         }
  1084.        if ((gal_type == GAL20V8) && (n == 13)) {
  1085.          fprintf(fp,"| /OE\n");
  1086.          flag = 1;
  1087.         }
  1088.       }
  1089.                             /*OLMC-Pin?*/
  1090.      if ( ((gal_type == GAL16V8) && (n >= 12) && (n <= 19)) ||
  1091.           ((gal_type == GAL20V8) && (n >= 15) && (n <= 22)) ) {
  1092.        if (gal_type == GAL16V8)
  1093.          k = n-12;
  1094.        else
  1095.          k = n-15;
  1096.        if (OLMC[k].PinType != INPUT)
  1097.          if (OLMC[k].PinType)
  1098.            fprintf(fp,"| Output\n");
  1099.          else
  1100.            fprintf(fp,"| NC\n");
  1101.        else
  1102.          fprintf(fp,"| Input\n");
  1103.       }
  1104.      else {
  1105.        if (!flag) 
  1106.          fprintf(fp,"| Input\n");
  1107.       }
  1108.     }
  1109.        if (fclose(fp)==EOF) {
  1110.      PrintText((UBYTE *)" Error! ",0);
  1111.      ErrorReq(8);            /*Datei läßt sich nicht schließen*/
  1112.      return;
  1113.     }
  1114.       }
  1115.      else {
  1116.        PrintText((UBYTE *)" Error! ",0);
  1117.        ErrorReq(13);
  1118.        return;
  1119.       }
  1120.      PrintText((UBYTE *)" o.k.",0);
  1121.     }
  1122. }
  1123.  
  1124.  
  1125.  
  1126. /* erstelle das Fuse-File*/
  1127. void WriteFuseFile()
  1128. {
  1129. extern    char    path;
  1130. FILE    *fp;
  1131. int    row, col, pin;
  1132. int    xor, ac1;
  1133.  
  1134.    if (MyFileReq((char *)"save fuse file",(char *)".fus",!Config.AutoSave)) {
  1135.     PrintText((UBYTE *)"saving fuse file...",1);
  1136.     if (fp=fopen(&path,(UBYTE *)"w")) {
  1137.        if (gal_type == GAL16V8)
  1138.      pin = 19;
  1139.        else
  1140.      pin = 22;
  1141.        for (row=0; row<ROW_SIZE; row++) {
  1142.      if (!((row) % 8)) {
  1143.        fprintf(fp,"\n\nPin %2d = ",pin);
  1144.        fprintf(fp,"%s",pinnames+(pin-1)*10);
  1145.        WriteSpaces(fp,13-strlen(pinnames+(pin-1)*10));
  1146.        if (gal_type == GAL16V8) {
  1147.          xor = Jedec.GALXOR[19-pin];
  1148.          ac1 = Jedec.GALAC1[19-pin];
  1149.         }
  1150.        else {
  1151.          xor = Jedec.GALXOR[22-pin];
  1152.          ac1 = Jedec.GALAC1[22-pin];
  1153.         }
  1154.        fprintf(fp,"XOR = %1d   AC1 = %1d",xor,ac1);
  1155.        pin--;    
  1156.       }
  1157.      fprintf(fp,"\n%2d ",row);
  1158.      for (col=0; col<num_of_col; col++) {
  1159.        if (!( (col) % 4) )
  1160.          fprintf(fp," ");
  1161.        if (Jedec.GALLogic[row * num_of_col + col])
  1162.          fprintf(fp,"-");
  1163.        else
  1164.          fprintf(fp,"x");
  1165.       }
  1166.     }
  1167.        fprintf(fp,"\n\n");
  1168.        if (fclose(fp)==EOF) {
  1169.      PrintText((UBYTE *)" Error! ",0);
  1170.      ErrorReq(8);            /*Datei läßt sich nicht schließen*/
  1171.      return;
  1172.     }
  1173.       }
  1174.      else {
  1175.        PrintText((UBYTE *)" Error! ",0);
  1176.        ErrorReq(13);
  1177.        return;
  1178.       }
  1179.      PrintText((UBYTE *)" o.k.",0);
  1180.     }
  1181. }
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187. /* schreibt Anzahl "numof" Spaces in File "fp"*/
  1188. void WriteSpaces(fp, numof)
  1189. FILE    *fp;
  1190. int    numof;
  1191. {
  1192. int n;
  1193.  
  1194.  for (n=0; n<numof; n++)
  1195.    fprintf(fp," ");
  1196. }
  1197.  
  1198.